package com.frank.loadinglibrary.special.cool.ball;

import com.frank.loadinglibrary.special.cool.CoolLoadingComponent;
import com.frank.loadinglibrary.utils.SimpleAnimatorListener;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorGroup;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.RectFloat;

public class ThirdCoolBall extends CoolBall {

    private Paint mPaint;
    // 第一个圆或圆环或圆弧的半径和画笔大小
    private float mFiCurR;
    private float mFiStrokeWidth;
    // 第二个圆或圆环或圆弧的半径和画笔大小
    private float mSeCurR;
    private float mSeStrokeWidth;
    // 正常圆(能停留的)最大的stroke
    private float STANDARD_MIN_R;
    // 前一个值
    private float mPreValue;
    // 当前值
    private float mCurValue;
    // 差值
    private float mDifValue;
    private AnimatorGroup mAnimatorSet;
    //根据状态绘制不同的图案
    private int mState;
    // 用于绘制绿色弧线
    private RectFloat mOval;
    // 用于绿色弧线的角度
    private int mAngle;
    // 绿色弧线开口的角度
    private static final int GAP_ANGLE = 240;
    private int mGapGreenAngle;
    // 用于绘制红色弧线
    private RectFloat mRedOval;
    // 用于绘制红色弧线的角度
    private int mRedAngle;
    // 用于绘制红色弧线的开口角度
    private int mGapRedAngle;
    // 黄色小球,用于弹出
    private SmallYellowBall mBall;
    //
    private boolean isStart = false;
    // 时间值
    private int mDuration1 = 600;
    private int mDuration2 = 600;
    private int mDuration3 = 4000;
    private int mDuration4 = 800;

    private int mEndCirIRadius;
    private int mEndCirMRadius;
    private int mEndCirORadius;
    private AnimatorValue mEndAnimator;
    // 小球移动结束,只绘制结束部分
    private boolean isMoveEnd = false;

    public ThirdCoolBall(float x, float y) {
        super(x, y);
    }

    @Override
    protected void initConfig() {
        super.initConfig();
        init();
    }

    private void init() {
        mEndMovingLength = -25;

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE_STYLE);

        // 初始化黄色小球
        mBall = new SmallYellowBall();
        mFiCurR = 45;
        mFiStrokeWidth = 30;
        mSeCurR = 15;
        mSeStrokeWidth = 15;
        STANDARD_MIN_R = 15;
    }

    @Override
    public void reset() {
        super.reset();
        isMoveEnd = false;
        // 初始化黄色小球
        mBall = new SmallYellowBall();
        mFiCurR = 45;
        mFiStrokeWidth = 30;
        mSeCurR = 15;
        mSeStrokeWidth = 15;
        STANDARD_MIN_R = 15;
    }

    @Override
    public void drawSelf(Canvas canvas) {
        super.drawSelf(canvas);
        if (!isMoveEnd) {
            switch (mState) {
                case 1:
                    mPaint.setStrokeWidth(mFiStrokeWidth);
                    mPaint.setColor(CoolLoadingComponent.GREEN);
                    canvas.drawCircle(getCurX(), getCurY(), mFiCurR - mFiStrokeWidth / 2, mPaint);

                    mPaint.setStrokeWidth(mSeStrokeWidth);
                    mPaint.setColor(CoolLoadingComponent.RED);
                    canvas.drawCircle(getCurX(), getCurY(), mSeCurR - mSeStrokeWidth / 2, mPaint);
                    break;
                case 2:
                    mPaint.setColor(CoolLoadingComponent.GREEN);
                    mPaint.setStrokeWidth(mFiStrokeWidth);
                    canvas.drawArc(mOval, new Arc(mAngle, GAP_ANGLE, false), mPaint);

                    mPaint.setStrokeWidth(mSeStrokeWidth);
                    mPaint.setColor(CoolLoadingComponent.YELLOW);
                    canvas.drawCircle(getCurX(), getCurY(), mSeCurR - mSeStrokeWidth / 2, mPaint);
                    break;
                case 3:
                    // 绘制红色弧线
                    mPaint.setStrokeWidth(mSeStrokeWidth);
                    mPaint.setColor(CoolLoadingComponent.RED);
                    canvas.drawArc(mRedOval, new Arc(mRedAngle, mGapRedAngle, false), mPaint);

                    mPaint.setColor(CoolLoadingComponent.GREEN);
                    mPaint.setStrokeWidth(mFiStrokeWidth);
                    canvas.drawArc(mOval, new Arc(mAngle, mGapGreenAngle, false), mPaint);

                    break;
                case 4:
                    // 绘制绿色圆
                    mPaint.setStrokeWidth(mSeStrokeWidth);
                    mPaint.setColor(CoolLoadingComponent.GREEN);
                    canvas.drawCircle(getCurX(), getCurY(), mSeCurR - mSeStrokeWidth / 2, mPaint);

                    // 绘制红色圆弧
                    mPaint.setStrokeWidth(mFiStrokeWidth);
                    mPaint.setColor(CoolLoadingComponent.RED);
                    canvas.drawCircle(getCurX(), getCurY(), mFiCurR - mFiStrokeWidth / 2, mPaint);

                    break;
                default:
                    break;
            }
        }

        if (mIsEnd) {
            if (!mIsEndAnimStart) {
                mEndAnimator.start();
                mIsEndAnimStart = true;
            }
            mPaint.setStyle(Paint.Style.FILL_STYLE);
            mPaint.setColor(CoolLoadingComponent.RED);
            canvas.drawCircle(getCurX(), getCurY(), mEndCirIRadius, mPaint);
            mPaint.setColor(CoolLoadingComponent.GREEN);
            canvas.drawCircle(getCurX(), getCurY(), mEndCirMRadius, mPaint);
            mPaint.setColor(CoolLoadingComponent.BLUE);
            canvas.drawCircle(getCurX(), getCurY(), mEndCirORadius, mPaint);
            mPaint.setStyle(Paint.Style.STROKE_STYLE);
            return;
        }

        mBall.drawSelf(canvas);
    }


    @Override
    protected void initAnim() {
        mAnimatorSet = new AnimatorGroup();
        // 放大弹出射线

        // 绿色圆弧包围红色圆,内部先产生间隔,红色圆膨胀,然后绿色圆弧和红色圆膨胀效果
        Animator flattenAnim = createFlattenAnim();
        // 等待黄色圆传递
//        ValueAnimator.ofFloat(0, 100)
        AnimatorValue waitForAnim = new AnimatorValue();
        waitForAnim.setDuration(mDuration2);
        // 黄色圆缩小,绿色弧线出现,旋转从0->-120,从-120->-240,抛出黄色小球,绿色弧线逐渐变成球,
        // 红色弧线绕圈,逐渐合并为圆环,
        Animator smallerAndRotateAnim = createSmallerAndRotateAnim();
        // 红色弧线往内缩,绿色圆放大,回到膨胀效果
        Animator backAnim = createBackAnim();

        mAnimatorSet.runSerially(flattenAnim, waitForAnim, smallerAndRotateAnim, backAnim);
        mAnimatorSet.setStateChangedListener(new SimpleAnimatorListener() {
            @Override
            public void onEnd(Animator animator) {
                super.onEnd(animator);
                if (mAnimatorStateListen != null) {
                    mAnimatorStateListen.onAnimatorEnd();
                }
            }
        });
    }

    /**
     * 绿色圆弧包围红色圆,内部先产生间隔,红色圆膨胀,然后绿色圆弧和红色圆膨胀效果
     *
     * @return
     */
    protected Animator createFlattenAnim() {
        // 产生间隔大小
        int gap = 4;
        // 红色内圆膨胀大小
        float redFlattenValue = mFiStrokeWidth - gap - mSeStrokeWidth;
        // 减去多一个值是因为内圆膨胀的时候,半径也会增加
        float bothFlattenValue = MAX_RADIUS_CIRCLE - mSeCurR - redFlattenValue / 2;
        // 绿色弧放大的速度,红色圆放大速率为1
        final float rate = (MAX_RADIUS_CIRCLE - mFiCurR) / bothFlattenValue;
        // 第一个参数
        float fiv = 0;
        // 第二个参数,外圆内半径扩大距离
        final float sev = gap;
        // 第三个参数,内圆半径扩大,stroke增大的范围
        final float thv = sev + redFlattenValue;
        // 第四个参数,内外圆同时扩大,最后同大小的范围
        float fov = thv + bothFlattenValue;
        AnimatorGroup flattenAnim = new AnimatorGroup();
//        AnimatorValue flattenAnim = ValueAnimator.ofFloat(fiv, sev, thv, fov);


        AnimatorValue animatorValue_1 = new AnimatorValue();
        animatorValue_1.setDuration((long) (mDuration1 / 3.0f));
        animatorValue_1.setLoopedCount(0);
        animatorValue_1.setValueUpdateListener((animatorValue, v) -> {
            mState = 1;
            mCurValue = (float) fiv + (sev - fiv) * v;
            mDifValue = mCurValue - mPreValue;
            // 外圆内半径扩大
            mFiStrokeWidth -= mDifValue;
            mFiCurR += mDifValue / 2;
            mPreValue = mCurValue;
        });
        animatorValue_1.setStateChangedListener(new SimpleAnimatorListener() {
            @Override
            public void onStart(Animator animator) {
                super.onStart(animator);
                mState = 1;
                mFiCurR = 45;
                mFiStrokeWidth = 30;
                mSeCurR = 15;
                mSeStrokeWidth = 15;
                // 小球不显示
                mBall.setShow(false);
            }
        });

        AnimatorValue animatorValue_2 = new AnimatorValue();
        animatorValue_2.setDuration((long) (mDuration1 / 3.0f));
        animatorValue_2.setLoopedCount(0);
        animatorValue_2.setValueUpdateListener((animatorValue, v) -> {
            mState = 1;
            mCurValue = (float) sev + (thv - sev) * v;
            mDifValue = mCurValue - mPreValue;
            // 内圆半径扩大,stroke增大
            mSeStrokeWidth += mDifValue;
            mSeCurR += mDifValue / 2;
            mPreValue = mCurValue;
        });

        AnimatorValue animatorValue_3 = new AnimatorValue();
        animatorValue_3.setDuration((long) (mDuration1 / 3.0f));
        animatorValue_3.setLoopedCount(0);
        animatorValue_3.setValueUpdateListener((animatorValue, v) -> {
            mState = 1;
            mCurValue = (float) thv + (fov - thv) * v;
            mDifValue = mCurValue - mPreValue;
            // 内外圆同时扩大,最后同大小
            mSeCurR += mDifValue;
            mFiCurR += mDifValue * rate;
            mPreValue = mCurValue;
        });

        animatorValue_3.setStateChangedListener(new SimpleAnimatorListener() {
            @Override
            public void onEnd(Animator animator) {
                super.onEnd(animator);
                mSeCurR = MAX_RADIUS_CIRCLE;
                mFiCurR = MAX_RADIUS_CIRCLE;
            }
        });

        flattenAnim.runSerially(animatorValue_1, animatorValue_2, animatorValue_3);

        return flattenAnim;
    }

    /**
     * 黄色圆缩小,绿色弧线出现,旋转从0->-120,从-120->-320(此时小球第一次击地,红色圆弧出现),从-320->-120(红色圆弧绕圈)
     * 抛出黄色小球,绿色弧线逐渐变成球,
     * 红色弧线绕圈,逐渐合并为圆环,
     *
     * @return
     */
    protected Animator createSmallerAndRotateAnim() {
        mOval = new RectFloat(getCurX(), getCurY(), getCurX(), getCurY());
        mRedOval = new RectFloat(getCurX() - MAX_RADIUS_CIRCLE + 5, getCurY() - MAX_RADIUS_CIRCLE + 5,
                getCurX() + MAX_RADIUS_CIRCLE - 5, getCurY() + MAX_RADIUS_CIRCLE - 5);
        mAngle = 0;
        // 绿色弧线默认弧长GAP_ANGLE=240
        mGapGreenAngle = GAP_ANGLE;
        // 根据角度来调整圆大小的缩放比例
        final float rate1 = (MAX_RADIUS_CIRCLE - STANDARD_MIN_R) / 120;
        final float rate2 = (MAX_RADIUS_CIRCLE - STANDARD_MIN_R) / 120;
        mRedAngle = 60;
        mGapRedAngle = 0;
        // 红色弧线开口逐渐合并
        final float gapRate = 360 / 420f;

        // 0->300->420->720
//        ValueAnimator smallerAnim = ValueAnimator.ofFloat(0, 720);
        AnimatorValue smallerAnim = new AnimatorValue();
        smallerAnim.setDuration(mDuration3);
        smallerAnim.setValueUpdateListener((animatorValue, v) -> {
            mCurValue = (float) 720 * v;
            if (mCurValue <= 120) {
                // 小黄球缩小
                mState = 2;
                mSeCurR = MAX_RADIUS_CIRCLE - mCurValue * rate1;
                mSeStrokeWidth = mSeCurR;
                mDifValue = mCurValue * rate1 + STANDARD_MIN_R - mFiStrokeWidth / 2;
                mOval.modify(getCurX() - mDifValue, getCurY() - mDifValue, getCurX() + mDifValue, getCurY() + mDifValue);
            } else if (mCurValue < 300) {
                // 小黄球停留
            } else {
                mState = 3;

                // 绿色圆弧缩小
                mGapGreenAngle = (int) (GAP_ANGLE + mCurValue - 300);
                if (mCurValue > 300 && mCurValue <= 420) {
                    mDifValue = MAX_RADIUS_CIRCLE - (mCurValue - 300) * rate2 - mFiStrokeWidth / 2;
                    mOval.modify(getCurX() - mDifValue, getCurY() - mDifValue, getCurX() + mDifValue, getCurY() + mDifValue);
                }

                // 红色弧线开始运动,逐渐合并为圆的状态,从开始到合并为圆弧0->420
                mSeStrokeWidth = 12;
                mGapRedAngle = (int) ((mCurValue - 300) * gapRate);
                mRedAngle = (int) mCurValue - 240;
            }
            if (mCurValue > 300 && mCurValue <= 310) {
                // 角度为300时, 抛出小黄球, 红色弧线开始运动
                mState = 3;
                if (!mBall.isShow()) {
                    mBall.setCurX(getCurX());
                    mBall.setCurY(getCurY());
                    mBall.setShow(true);
                    mBall.throwOut();
                }
            }
            // 绿色圆弧绕圈
            mAngle = (int) (-720 * v);
        });
        smallerAnim.setStateChangedListener(new SimpleAnimatorListener() {
            @Override
            public void onEnd(Animator animator) {
                super.onEnd(animator);
                mState = 4;
                mFiStrokeWidth = 15;
                mFiCurR = MAX_RADIUS_CIRCLE;
                mSeStrokeWidth = 30;
                mSeCurR = 16f;
            }
        });
        return smallerAnim;
    }

    /**
     * 红色弧线往内缩,绿色圆放大,回到膨胀效果
     *
     * @return
     */
    protected Animator createBackAnim() {
        final float rate = (MAX_RADIUS_CIRCLE - 45) / 30F;
        //ValueAnimator.ofFloat(45, STANDARD_MIN_R);
        AnimatorValue backAnim = new AnimatorValue();
        backAnim.setDuration(mDuration4);
        backAnim.setValueUpdateListener((animatorValue, v) -> {
            if (!isStart) {
                return;
            }
            mState = 4;
            mCurValue = 45 + (STANDARD_MIN_R - 45) * v;
            mDifValue = mPreValue - mCurValue;
            // 红色圆弧缩小
            mFiStrokeWidth = 15;
            mFiCurR -= mDifValue * (1 + rate);

            // 绿色圆放大
            mSeStrokeWidth = 30;
            mSeCurR += mDifValue;
            mPreValue = mCurValue;
        });
        backAnim.setStateChangedListener(new SimpleAnimatorListener() {
            @Override
            public void onStart(Animator animator) {
                super.onStart(animator);

                isStart = true;
                mState = 4;
                mPreValue = 45;
                mCurValue = 45;
            }

            @Override
            public void onEnd(Animator animator) {
                super.onEnd(animator);
                isStart = false;
            }
        });
        return backAnim;
    }

    @Override
    public void startAnim() {
        mAnimatorSet.start();
    }

    @Override
    protected void initEndAnim() {
        //ValueAnimator.ofFloat(0, 1, 2)
        mEndAnimator = new AnimatorValue();
        mEndAnimator.setDuration(mDuration);
//        mEndAnimator.setRepeatCount(2);
        mEndAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                float zoroToOne = (float) 2 * v;
                if (zoroToOne <= 1.0f) {
                    mCurX = (int) (mPerX + zoroToOne * mEndMovingLength);
                    mEndCirIRadius = (int) (MAX_RADIUS_CIRCLE * zoroToOne);
                    if (zoroToOne <= 0.5f) {
                        zoroToOne = 2 * zoroToOne;
                    } else {
                        zoroToOne = 1 - 2 * (zoroToOne - 0.5f);
                    }
                    mEndCirMRadius = (int) (MAX_RADIUS_CIRCLE * zoroToOne);
                } else {
                    if (!isMoveEnd) {
                        isMoveEnd = true;
                        if (mAnimatorStateListen != null) {
                            mAnimatorStateListen.onMoveEnd();
                        }
                    }

                    zoroToOne = 2 - zoroToOne;
                    mEndCirIRadius = (int) (MAX_RADIUS_CIRCLE * zoroToOne);
                    if (zoroToOne >= 0.5f) {
                        zoroToOne = (1.0f - zoroToOne) * 2;
                    } else {
                        zoroToOne = zoroToOne * 2;
                    }
                    mEndCirORadius = (int) (MAX_RADIUS_CIRCLE * zoroToOne);
                }
            }
        });
    }


}
